Date.now = Date.now || function() {
    return new Date().getTime();
};

var SEQUENCE = Date.now(), noop = function() {}, getCwarn = function() {
    var e = "object" == typeof console ? console.warn : noop;
    try {
        var t = {
            warn: e
        };
        t.warn.call(t);
    } catch (r) {
        return noop;
    }
    return e;
}, util = {
    noop: noop,
    warn: getCwarn(),
    key: "__bl",
    selfErrKey: "ARMS_SDK_ERROR",
    selfErrPage: "ARMSSDK",
    win: "object" == typeof window && window.document ? window : undefined,
    regionMap: {
        cn: "https://arms-retcode.aliyuncs.com/r.png?",
        sg: "https://arms-retcode-sg.aliyuncs.com/r.png?",
        sg_2: "https://retcode-sg-lazada.arms.aliyuncs.com/r.png?",
        daily: "http://arms-retcode-daily.alibaba.net/r.png?",
        daily_2: "https://arms-retcode-daily.alibaba.net/r.png?",
        us: "https://retcode-us-west-1.arms.aliyuncs.com/r.png?",
        tw: "https://arms-retcode.orientalgame.com.tw/r.png?",
        tw_sg: "https://arms-retcode-sg.orientalgame.com.tw/r.png?",
        hz_finance: "https://arms-retcode-hz-finance.aliyuncs.com/r.png?"
    },
    defaultImgUrl: "https://arms-retcode.aliyuncs.com/r.png?",
    createObject: function(e) {
        if (Object.create) return Object.create(e);
        var t = function() {};
        return t.prototype = e, new t();
    },
    each: function(e, t) {
        var r = 0, n = e.length;
        if (this.T(e, "Array")) for (;r < n && !1 !== t.call(e[r], e[r], r); r++) ; else for (r in e) if (!1 === t.call(e[r], e[r], r)) break;
        return e;
    },
    safetyCall: function(e, t, r) {
        if ("function" != typeof e) return r;
        try {
            return e.apply(this, t);
        } catch (n) {
            return r;
        }
    },
    T: function(e, t) {
        var r = Object.prototype.toString.call(e).substring(8).replace("]", "");
        return t ? r === t : r;
    },
    filterByRule: function(e, t) {
        if (!e) return "";
        if (!t) return e;
        var r = this, n = r.T(t);
        return "Function" === n ? r.safetyCall(t, [ e ], e) : "Array" === n ? (this.each(t, function(t) {
            e = r.filterByRule(e, t);
        }), e) : "Object" === n ? e.replace(t.rule, t.target || "") : e.replace(t, "");
    },
    ignoreByRule: function(e, t) {
        if (!e || !t) return !1;
        if ((this.isString(t) || t.source || "Function" === this.T(t)) && (t = [ t ]), !this.isArray(t)) return this.warn("[arms] invalid rules of ignore config, (list of) String/RegExp/Funcitons are available"), 
        !1;
        for (var r, n = [], o = 0, i = t.length; o < i; o++) if (r = t[o], this.isString(r)) n.push(r.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); else if (r && r.source) n.push(r.source); else if (r && "Function" === this.T(r) && !0 === this.safetyCall(r, [ e ], !1)) return !0;
        var a = new RegExp(n.join("|"), "i");
        return !!(n.length && a.test && a.test(e));
    },
    J: function(e) {
        if (!e || "string" != typeof e) return e;
        var t = null;
        try {
            t = JSON.parse(e);
        } catch (r) {}
        return t;
    },
    pick: function(e) {
        return 1 === e || 1 === Math.ceil(Math.random() * e);
    },
    verifyConfig: function(e) {
        if ("sample" in e) {
            var t = e.sample, r = t;
            t && /^\d+(\.\d+)?%$/.test(t) && (r = parseInt(100 / parseFloat(t))), 0 < r && 1 > r && (r = parseInt(1 / r)), 
            r >= 1 && r <= 100 ? e.sample = r : delete e.sample;
        }
        return e;
    },
    on: function(e, t, r, n, o) {
        return e.addEventListener ? (o = o || !1, e.addEventListener(t, function i(a) {
            n && e.removeEventListener(t, i, o), r.call(this, a);
        }, o)) : e.attachEvent && e.attachEvent("on" + t, function a(o) {
            n && e.detachEvent("on" + t, a), r.call(this, o);
        }), this;
    },
    off: function(e, t, r) {
        return r ? (e.removeEventListener ? e.removeEventListener(t, r) : e.detachEvent && e.detachEvent(t, r), 
        this) : this;
    },
    delay: function(e, t) {
        return -1 === t ? (e(), null) : setTimeout(e, t || 0);
    },
    ext: function(e) {
        for (var t = 1, r = arguments.length; t < r; t++) {
            var n = arguments[t];
            for (var o in n) Object.prototype.hasOwnProperty.call(n, o) && (e[o] = n[o]);
        }
        return e;
    },
    sub: function(e, t) {
        var r = {};
        return this.each(e, function(e, n) {
            -1 !== t.indexOf(n) && (r[n] = e);
        }), r;
    },
    uu: function() {
        for (var e, t, r = 20, n = new Array(r), o = Date.now().toString(36).split(""); r-- > 0; ) t = (e = 36 * Math.random() | 0).toString(36), 
        n[r] = e % 3 ? t : t.toUpperCase();
        for (var i = 0; i < 8; i++) n.splice(3 * i + 2, 0, o[i]);
        return n.join("");
    },
    seq: function() {
        return (SEQUENCE++).toString(36);
    },
    decode: function(e) {
        try {
            e = decodeURIComponent(e);
        } catch (t) {}
        return e;
    },
    encode: function(e, t) {
        try {
            e = t ? encodeURIComponent(e).replace(/\(/g, "%28").replace(/\)/g, "%29") : encodeURIComponent(e);
        } catch (r) {}
        return e;
    },
    serialize: function(e) {
        e = e || {};
        var t = [];
        for (var r in e) Object.prototype.hasOwnProperty.call(e, r) && e[r] !== undefined && t.push(r + "=" + this.encode(e[r], "msg" === r));
        return t.join("&");
    },
    checkAPI: function(e, t) {
        if (!e || "string" != typeof e) return !1;
        var r = /arms-retcode[\w-]*\.aliyuncs/.test(e);
        return !r && t && (r = /(\.png)|(\.gif)|(alicdn\.com)/.test(e)), !r;
    },
    checkAutoError: function(e) {
        return !(!e || !e.message) && !/failed[\w\s]+fetch/i.test(e.message);
    },
    cutUrlSearch: function(e) {
        return e && "string" == typeof e ? e.replace(/^(https?:)?\/\//, "").replace(/\?.*$/, "") : "";
    },
    removeUrlSearch: function(e) {
        return e && "string" == typeof e ? e.replace(/\?.*$/, "") : "";
    },
    createFakeToString: function(e) {
        return function() {
            return e + "() { [native code] }";
        };
    },
    checkSameOrigin: function(e, t) {
        if (!t || !e) return !1;
        var r = "//" + t.split("/")[2];
        return e === t || e.slice(0, t.length + 1) === t + "/" || e === r || e.slice(0, r.length + 1) === r + "/" || !/^(\/\/|http:|https:).*/.test(e);
    },
    getRandIP: function() {
        for (var e = [], t = 0; t < 4; t++) {
            var r = Math.floor(256 * Math.random());
            e[t] = (r > 15 ? "" : "0") + r.toString(16);
        }
        return e.join("").replace(/^0/, "1");
    },
    getSortNum: function(e) {
        return e ? (e += 1) >= 1e3 && e <= 9999 ? e : e < 1e3 ? e + 1e3 : e % 1e4 + 1e3 : 1e3;
    },
    getRandNum: function(e) {
        return e && "string" == typeof e ? e.length < 5 ? this.getNum(5) : e.substring(e.length - 5) : this.getNum(5);
    },
    getNum: function(e) {
        for (var t = [], r = 0; r < e; r++) {
            var n = Math.floor(16 * Math.random());
            t[r] = n.toString(16);
        }
        return t.join("");
    },
    getCurDomain: function() {
        return location && location.hostname || "";
    },
    parseFetchHeaders: function(e) {
        if (!e) return {};
        var t = {};
        try {
            if ("function" == typeof e.keys) for (var r = e.keys(), n = r.next(); !n.done; ) {
                var o = n.value;
                t[o] = e.get(o), n = r.next();
            } else t = e;
        } catch (i) {
            t = {};
        }
        return t;
    },
    parseXhrHeaders: function(e) {
        if (!e && "string" != typeof e) return {};
        var t = {};
        try {
            var r = e.split("\r\n");
            t = r.reduce(function(e, t) {
                var r = t.split(": ");
                return e[r[0]] = r[1], e;
            }, {});
        } catch (n) {
            t = {};
        }
        return t;
    },
    getQuerys: function(e) {
        if (!e) return "";
        var t = {}, r = [], n = "", o = "";
        try {
            var i = [];
            if (e.indexOf("?") >= 0 && (i = e.substring(e.indexOf("?") + 1, e.length).split("&")), 
            i.length > 0) for (var a in i) n = (r = i[a].split("="))[0], o = r[1], t[n] = o;
        } catch (s) {
            t = {};
        }
        return t;
    },
    getFetchSnapshot: function(e, t, r) {
        var n, o;
        try {
            var i = (e && "string" != typeof e[0] ? e[0].url : e[0]) || "", a = (e && "string" != typeof e[0] ? e[0] : e[1]) || {}, s = "POST" === a.method.toUpperCase() ? a.body : this.getQuerys(i);
            n = {
                originApi: i,
                method: a.method || "unknown",
                params: s,
                response: t || "",
                reqHeaders: this.parseFetchHeaders(a.headers || null),
                resHeaders: this.parseFetchHeaders(r)
            }, o = "function" == typeof encodeURIComponent && JSON && encodeURIComponent(JSON.stringify(n)) || "{}";
        } catch (c) {
            o = "{}";
        }
        return o;
    },
    getXhrSnapshot: function(e, t, r) {
        if (!e || !t || !r) return {};
        var n, o;
        try {
            var i = "";
            "" === r.responseType || "text" === r.responseType ? i = r.responseText : "document" === r.responseType && (i = r.responseXML), 
            n = {
                originApi: e,
                method: t,
                params: this.getQuerys(e),
                response: i,
                reqHeaders: {},
                resHeaders: this.parseXhrHeaders("function" == typeof r.getAllResponseHeaders && r.getAllResponseHeaders() || "")
            }, o = "function" == typeof encodeURIComponent && JSON && encodeURIComponent(JSON.stringify(n)) || "{}";
        } catch (a) {
            o = "{}";
        }
        return o;
    },
    isRobot: function() {
        var e = [ "nuhk", "googlebot/", "googlebot-image", "yammybot", "openbot", "slurp", "msnbot", "ask jeeves/teoma", "ia_archiver", "baiduspider", "bingbot/", "adsbot" ];
        if (!navigator || "string" != typeof navigator.userAgent) return !1;
        try {
            for (var t = navigator.userAgent.toLowerCase(), r = 0; r < e.length; r++) {
                var n = e[r];
                if (t.lastIndexOf(n) >= 0) return !0;
            }
        } catch (o) {
            this.warn("[arms] useragent parse error");
        }
        return !1;
    },
    isFunction: function(e) {
        return "function" == typeof e;
    },
    isPlainObject: function(e) {
        return "[object Object]" === Object.prototype.toString.call(e);
    },
    isString: function(e) {
        return "[object String]" === Object.prototype.toString.call(e);
    },
    isArray: function(e) {
        return "[object Array]" === Object.prototype.toString.call(e);
    },
    joinRegExp: function(e) {
        for (var t, r = [], n = 0, o = e.length; n < o; n++) t = e[n], this.isString(t) ? r.push(t.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")) : t && t.source && r.push(t.source);
        return new RegExp(r.join("|"), "i");
    },
    reWriteMethod: function(e, t, r) {
        if (null !== e) {
            var n = e[t];
            e[t] = r(n);
        }
    },
    checkSDKError: function(e, t) {
        if (!e && !t) return !1;
        if (new RegExp(this.selfErrKey, "i").test(e)) return !0;
        return !!this.ignoreByRule(t, [ /retcode.alicdn.com\/retcode\/bl.js/, /g.alicdn.com\/retcode\/cloud-sdk\/bl.js/, /laz-g-cdn.alicdn.com\/retcode\/cloud-sdk\/bl.js/, /local.taobao.com:8880\/build\/bl/ ]);
    },
    sdkError: function(e) {
        return {
            msg: e,
            message: this.selfErrKey
        };
    },
    dealParam: function(e, t, r) {
        var n = {};
        try {
            n = this.isPlainObject(e) ? this.ext({
                key: e.key || "default",
                val: e.val || e.value || r
            }, e, {
                begin: Date.now()
            }) : {
                key: e || "default",
                val: t || r,
                begin: Date.now()
            };
        } catch (o) {
            this.warn("[retcode] baseLog error: " + o);
        }
        return n;
    }
};

module.exports = util;